<template>
  <div>
    <a-spin :tip="loadTips" :spinning="spinning" size="large">
      <a-form layout="horizontal" :rules="pwdRules" :model="formPwd" @finish="handleSubmit">
        <a-form-item
          style="display: flex; align-items: center; justify-content: center; align-content: center"
        >
          <div style="font-size: 28px; text-align: center">用户登录</div>
        </a-form-item>
        <a-form-item required hasFeedback name="username">
          <a-input v-model:value="formPwd.username" size="large" placeholder="请输入用户名">
            <template #prefix
              ><user-outlined type="user" :style="{ color: 'rgba(0,0,0,.25)' }"
            /></template>
          </a-input>
        </a-form-item>
        <a-form-item required hasFeedback name="password">
          <a-input
            v-model:value="formPwd.password"
            size="large"
            type="password"
            placeholder="请输入密码"
          >
            <template #prefix
              ><lock-outlined type="user" :style="{ color: 'rgba(0,0,0,.25)' }"
            /></template>
          </a-input>
        </a-form-item>
        <div id="captcha" style="width: 450px; max-height: 40px; margin-bottom: 22px"></div>
        <a-form-item>
          <a-button type="primary" html-type="submit" size="large" :loading="loading" block>
            登录
          </a-button>
        </a-form-item>
      </a-form>
      <div>
        <router-link class="register" :to="{ name: 'register' }">注册账户</router-link>
        <router-link :to="{ name: 'ForgotPassword' }" class="forge-password" style="float: right">
          忘记密码
        </router-link>
      </div>
      <a-divider>第三方登录</a-divider>
      <div
        style="display: flex; align-items: center; align-content: center; justify-content: center"
      >
        <a style="margin: 0px 10px" title="使用微信帐号登录" @click="wechatLogin"
          ><WechatOutlined :style="{ fontSize: '26px', color: '#07c160' }"
        /></a>
      </div>
      <div
        style="
          display: flex;
          align-items: center;
          align-content: center;
          justify-content: center;
          margin-top: 30px;
        "
      >
        <a-button type="link" danger @click="clickFeedback"
          >登录不了？我要反馈(采纳可获赠1个月会员时长)</a-button
        >
      </div>
    </a-spin>
    <a-modal
      v-model:open="wechat_qrcode_visible"
      title="请扫描二维码登录"
      :footer="null"
      width="350px"
    >
      <a-qrcode
        v-if="loginStatus.cd === 0"
        :value="qrcodeUrl"
        :status="qrcodeStatus"
        size="302"
        @refresh="wechatLogin"
      />
      <a-result v-if="loginStatus.cd < 0" status="warning" :title="loginStatus.msg" />
      <a-result v-if="loginStatus.cd == 200" status="success" :title="loginStatus.msg" />
    </a-modal>
    <a-modal
      v-model:open="feedShow"
      title="我要反馈"
      style="width: 700px; height: 1000px"
      :footer="null"
    >
      <iframe
        :src="feedbackUrl"
        frameborder="no"
        border="0"
        marginwidth="0"
        marginheight="0"
        scrolling="no"
        allowtransparency="true"
        style="width: 100%; height: 1000px"
      ></iframe>
    </a-modal>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs, ref, onMounted, watch } from 'vue'
import { message, Divider, Spin, QRCode, Result } from 'ant-design-vue'

import {
  UserOutlined,
  LockOutlined,
  MobileOutlined,
  MailOutlined,
  WechatOutlined
} from '@ant-design/icons-vue'
import { useRoute, useRouter } from 'vue-router'
import { requestSuccess, requestFailed } from '@/utils/feedback'
import { getSmsCaptcha, getWxLoginStatus, getWxLoginQrcode } from '@/api/system/user'
import { getLoginParam } from '@/api/common'
import {
  validatePhone,
  validatePassword,
  validateCaptcha,
  validateUserName
} from '@/utils/validate'
import { useStore } from '@/store'
import { SvgIcon } from '@/components/svg-icon'
import CryptoJS from 'crypto-js'

export default defineComponent({
  name: 'Login',
  components: {
    UserOutlined,
    LockOutlined,
    WechatOutlined,
    SvgIcon,
    MobileOutlined,
    MailOutlined,
    [Spin.name]: Spin,
    [QRCode.name]: QRCode,
    [Result.name]: Result,
    [Divider.name]: Divider
  },
  setup() {
    const state = reactive<any>({
      loading: false,
      wechat_qrcode_visible: false,
      feedShow: false,
      spinning: false,
      feedbackUrl: 'https://plus.21ds.cn/feedback/index.html?id=FSI4894117794504276',
      socket: null,
      loadTips: '登录中',
      activeKey: ref('tab1'),
      setting: {},
      qrData: {},
      loginStatus: {
        cd: 0
      },
      interval: 0,
      qrcodeStatus: 'loading',
      qrcodeNum: 0,
      qrcodeUrl: '',
      qrToken: '',
      wechatData: {
        code: '',
        type: ''
      },
      formPwd: {
        username: '',
        authenticate: '',
        token: '',
        password: ''
      },
      formMobile: {
        mobile: '',
        authenticate: '',
        token: '',
        captcha: ''
      },
      state: {
        smsSendBtn: false,
        time: 60
      }
    })
    const store = useStore()
    const router = useRouter()
    const route = useRoute()

    watch(
      () => state.wechat_qrcode_visible,
      () => {
        if (state.wechat_qrcode_visible === false) {
          state.qrcodeStatus = 'loading'
          clearInterval(state.interval)
          if (
            state.socket != null &&
            state.socket.connected != undefined &&
            state.socket.connected === true
          ) {
            state.socket.disconnect()
          }
        }
      }
    )

    if (route.query?.state == 'wx_login' && route.query.code) {
      state.spinning = true
      state.loadTips = '微信登录中……'
      state.wechatData.code = route.query.code
      state.wechatData.type = 'wx_login'
      oauthLogin(state.wechatData)
    }
    if (route.query?.state == 'ww_login' && route.query.code) {
      state.spinning = true
      state.loadTips = '企业微信登录中……'
      state.wechatData.code = route.query.code
      state.wechatData.type = 'ww_login'
      oauthLogin(state.wechatData)
    }

    function clickFeedback() {
      state.feedbackUrl =
        'https://plus.21ds.cn/feedback/index.html?id=FSI4894117794504276&params={"登录用户":"' +
        state.formPwd.username +
        '"}'
      state.feedShow = true
    }

    const startSocketStatus = () => {
      if (state.socket) {
        state.socket.disconnect()
      }
      let wsQuery = {}
      wsQuery['ws_id'] = 'SI4924539635987626'
      wsQuery['ws_sign'] = CryptoJS.SHA256(
        wsQuery['ws_id'] + '969093b6fe8330b9ef40e789989e713d'
      ).toString()
      state.socket = (window as any).io('wss://21ds.cn', {
        // autoConnect: true,
        reconnection: true,
        upgrade: true,
        reconnectionDelay: 1000,
        reconnectionDelayMax: 1000,
        reconnectAttempts: 5,
        query: wsQuery,
        transports: ['websocket']
      })
      state.socket.on('connect', () => {
        console.log('Socket连接成功(21ds.cn)')
        setTimeout(() => {
          state.qrcodeStatus = 'expired'
          clearInterval(state.interval)
          state.socket.disconnect()
        }, 110000)
        state.socket.emit(
          'join-room',
          JSON.stringify({ union_id: state.qrData.union_id, to_all: 0 }),
          () => {}
        )
      })
      state.socket.on('disconnect', (message) => {
        console.log('Socket断开连接(21ds.cn)', message)
      })
      state.socket.on('event', () => {
        // console.log(message)
      })
      state.socket.on('join-room', () => {
        // state.socket.emit(
        //   'say',
        //   { room: state.qrData.room, to_all: 1, message: 'hello world' },
        //   (res) => {
        //     console.log(res)
        //   }
        // )
        console.log('登录通道已连接')
      })
      state.socket.on('say', (message) => {
        const messageObj = JSON.parse(message)
        const result = JSON.parse(messageObj.message)
        if (result.cd != undefined && result.cd == 200) {
          store
            .dispatch('user/qrcode_login', result)
            .then((res) => {
              if (res.cd == 200) {
                loginSuccess()
              } else {
                requestFailed(res)
              }
            })
            .catch((err) => {
              requestFailed(err)
            })
            .finally(() => {
              state.formPwd.token = ''
            })
        }
      })
    }
    onMounted(() => {
      getSetting()
      setTimeout(function () {
        ;(window as any).captchaInit('4960354834839720')
      }, 100)
    })

    const initCaptcha = () => {
      ;(window as any).showCaptcha('4960354834839720', '#captcha').then(function (res) {
        if (state.activeKey == 'tab1') {
          state.formPwd.token = res
          handleSubmit()
        } else {
          state.formMobile.token = res
          getCaptcha()
        }
      })
    }
    const loginSuccess = () => {
      state.qrcodeStatus = 'expired'
      state.wechat_qrcode_visible = false
      clearInterval(state.interval)
      const toPath = decodeURIComponent((route.query?.redirect || '/dashboard/Workplace') as string)
      requestSuccess(null, '登录成功')
      router.replace(toPath).then(() => {
        if (route.name == 'login') {
          router.replace('/')
        }
      })
    }

    const getSetting = () => {
      getLoginParam({})
        .then((res) => {
          state.setting = res
        })
        .catch((err) => {
          console.log(err)
        })
    }

    function oauthLogin(data) {
      store
        .dispatch('user/login', data)
        .then((res) => {
          if (res.code == 200) {
            loginSuccess()
          } else {
            requestFailed(res)
          }
        })
        .catch((err) => {
          requestFailed(err)
        })
        .finally(() => {
          state.spinning = false
          state.loading = false
          message.destroy()
        })
    }

    const pwdRules = {
      username: [
        {
          required: true,
          message: '请输入用户名',
          trigger: ['blur', 'change']
        },
        {
          validator: validateUserName,
          trigger: ['blur', 'change']
        }
      ],
      password: [
        {
          required: true,
          message: '请输入密码',
          trigger: ['blur', 'change']
        },
        {
          validator: validatePassword,
          trigger: ['blur', 'change']
        }
      ]
    }
    const mobileRules = {
      mobile: [
        {
          required: true,
          message: '请输入手机号',
          trigger: ['blur', 'change']
        },
        {
          validator: validatePhone,
          trigger: 'change'
        }
      ],
      captcha: [
        {
          required: true,
          message: '请输入验证码',
          trigger: ['blur', 'change']
        },
        {
          validator: validateCaptcha,
          trigger: ['blur', 'change']
        }
      ]
    }

    const wechatLogin = () => {
      state.wechat_qrcode_visible = true
      getWxLoginQrcode()
        .then((res) => {
          state.qrcodeStatus = 'active'
          state.qrcodeUrl = res.url
          state.qrToken = res.token
          state.qrData = res
          wechatLoginStatus()
        })
        .catch((err) => {
          console.log(err)
        })
    }
    const wechatLoginStatus = () => {
      startSocketStatus()
      setTimeout(() => {
        if (
          state.socket != null &&
          state.socket.connected != undefined &&
          state.socket.connected === true
        ) {
          return false
        }
        state.interval = setInterval(() => {
          if (state.qrcodeNum >= 120) {
            state.qrcodeStatus = 'expired'
            clearInterval(state.interval)
          }
          state.qrcodeNum++
          getWxLoginStatus({ token: state.qrToken })
            .then((res) => {
              state.loginStatus = res
              if (res.cd == 200) {
                store
                  .dispatch('user/qrcode_login', res)
                  .then((res) => {
                    if (res.cd == 200) {
                      loginSuccess()
                    } else {
                      requestFailed(res)
                    }
                  })
                  .catch((err) => {
                    requestFailed(err)
                  })
                  .finally(() => {
                    state.formPwd.token = ''
                    message.destroy()
                  })
              }
            })
            .catch((err) => {
              console.log(err)
            })
        }, 1000)
      }, 800)
    }
    const wwLogin = () => {
      state.wechat_qrcode_visible = true
      setTimeout(() => {
        ;(window as any).WwLogin({
          id: 'wechat_qrcode',
          appid: state.setting.ww_appid,
          agentid: state.setting.ww_agentid,
          redirect_uri: window.location.href,
          state: 'ww_login',
          href: ''
        })
      }, 300)
    }

    function handleSubmit() {
      if (state.formPwd.token == '') {
        initCaptcha()
        return false
      }
      state.loading = true
      store
        .dispatch('user/login', state.formPwd)
        .then((res) => {
          if (res.code == 200) {
            loginSuccess()
          } else {
            requestFailed(res)
          }
        })
        .catch((err) => {
          requestFailed(err)
        })
        .finally(() => {
          state.loading = false
          state.formPwd.token = ''
          message.destroy()
        })
    }
    function mobileSubmit() {
      if (state.formMobile.token == '') {
        initCaptcha()
        return false
      }
      state.loading = true
      store
        .dispatch('user/login', state.formMobile)
        .then((res) => {
          if (res.code == 200) {
            loginSuccess()
          } else {
            requestFailed(res)
          }
        })
        .catch((err) => {
          requestFailed(err)
        })
        .finally(() => {
          state.loading = false
          message.destroy()
        })
    }
    let interval = window.setInterval(() => {})
    function getCaptcha() {
      if (state.state.smsSendBtn == true) {
        return false
      }
      if (!state.formMobile.mobile) {
        requestFailed(null, '请输入手机号')
        return false
      }
      if (state.formMobile.token == '') {
        initCaptcha()
        return false
      }
      state.state.smsSendBtn = true
      interval = window.setInterval(() => {
        if (state.state.time-- <= 0) {
          state.state.time = 60
          state.state.smsSendBtn = false
          window.clearInterval(interval)
        }
      }, 1000)
      let hide = message.loading('验证码发送中..', 0)
      getSmsCaptcha({
        phone: state.formMobile.mobile,
        authenticate: state.formMobile.authenticate,
        token: state.formMobile.token,
        type: 'login'
      })
        .then((res) => {
          setTimeout(hide, 1000)
          if (res.code === 200) {
            requestSuccess(null, '验证码获取成功')
          } else {
            setTimeout(hide, 1)
            clearInterval(interval)
            state.state.time = 60
            state.state.smsSendBtn = false
            requestFailed(res)
          }
        })
        .catch((err) => {
          console.log(err)
          setTimeout(hide, 1)
          clearInterval(interval)
          state.state.time = 60
          state.state.smsSendBtn = false
          requestFailed(err)
        })
        .finally(() => {
          state.formMobile.token = ''
        })
    }
    return {
      ...toRefs(state),
      handleSubmit,
      interval,
      oauthLogin,
      mobileSubmit,
      mobileRules,
      clickFeedback,
      pwdRules,
      wechatLogin,
      wwLogin,
      getCaptcha
    }
  }
})
</script>

<style lang="scss" scoped>
::v-deep(.ant-tabs-nav) {
  width: 100% !important;
  .ant-tabs-tab {
    width: 45% !important;
    text-align: center;
  }
}
</style>
